import pprint

from bson import ObjectId

from config import col_activity, col_register, col_institution, col_alumni, col_top11, col_okr, col_top11e
from datetime import datetime, timedelta


def inst_query(inst_id):
    inst_id = ObjectId(inst_id)

    return {"$or": [{"institution_id": inst_id},
                    {"co_inst_ids": inst_id}]}


def month_range(year, month=1):
    s_m = month
    e_m = month + 1
    s_y = year
    e_y = year
    # next year
    if e_m > 12:
        e_y = e_y + 1
        e_m = e_m % 12

    from_date = datetime(s_y, s_m, 1)  # 默认当前年份的第一天的时刻 epoch_year
    to_date = datetime(e_y, e_m, 1)

    return {"$gte": from_date,
            "$lt": to_date}


def task_top_by_month(inst_id: str, year, month=0):
    """
    详细榜单
    """
    year = year if year else datetime.utcnow().year
    month = month if month else datetime.utcnow().month
    query = inst_query(inst_id)
    query["is_deleted"] = {"$ne": True}

    query['end_time'] = month_range(year, month)

    act_docs = col_activity.find(query).distinct("_id")
    total_activities = len(act_docs)

    pipeline = [
        {"$match": {"is_attended": True, "activity_id": {"$in": list(act_docs)}}},
        {"$lookup": {
            "from": "alumni",
            "let": {"person_ref_id": "$person_id"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$person_ref_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"name_zh": 1, "_id": 0,"self_label":1,"has_valid_identify": {
                    "$and": [
                        {"$ne": ["$identify_photo", None]},
                        {"$ne": ["$identify_id", None]}
                    ]
                }}}
            ],
            "as": 'persons'
        }},
        # 过滤无效的引用
        {"$match": {"persons.0": {"$exists": True}}},
        {"$unwind": "$persons"},
        {"$project": {"refs_participants": 1, "person_id": 1, "activity_id": 1, "persons.self_label": 1,"persons.has_valid_identify": 1}},
    ]


    reg_docs = col_register.aggregate(pipeline)

    reg_docs = list(reg_docs) if reg_docs else []
    # 加入的统计
    total_with_valid_identify = sum(doc["persons"]["has_valid_identify"] for doc in reg_docs)
    total_participants = len(reg_docs)

    # 质量指标
    quality_index_count = 0
    # 激活指标
    activate_indicators_count = 0
    # 数量指标
    quantity_indicators_count = 0

    # activate_indicators 多次参加活动记为1次
    persons = set()
    for doc in reg_docs:
        _label = doc.get("persons", {}).get("self_label", [])
        if _label in ["两院院士", "科协委员"]:
            quality_index_count += 1
            if doc.get("person_id") not in persons:
                activate_indicators_count += 1
                persons.add(doc.get("person_id"))

    refs_participants = len([ref for ref in reg_docs if ref.get("refs_participants", 0)])
    total_service = total_participants + refs_participants + total_with_valid_identify

    okr = col_okr.find_one({"year": year, "dept_id": inst_id})
    if okr:
        ration = round(total_service / okr.get("okr", 0.000001), 6)
        col_top11.update_one({"dept_id": inst_id, "year": year, "month": month},
                             {"$set": {"total_activities": total_activities,
                                       "total_participants": total_participants,
                                       "quality_index_count": quality_index_count,
                                       "activate_indicators_count": activate_indicators_count,
                                       "quantity_indicators_count":quantity_indicators_count,
                                       "refs_participants": refs_participants,
                                       "total_service": total_service,
                                       "target": okr.get("okr", 0.000001),
                                       "ration": ration,
                                       "label": okr.get("dept_label"),
                                       "update": datetime.utcnow()
                                       }}, upsert=True)


def task_top_ranking_v2(inst_id: str, year=None):
    """折算后新榜单（同1个单位同1年份内全部活动联系同一个科技者最多算2次）"""
    year = year if year else datetime.utcnow().year
    query = inst_query(inst_id)
    query["is_deleted"] = {"$ne": True}

    from_date = datetime(year, 1, 1)  # 默认当前年份的第一天的时刻epoch_year
    to_date = datetime(year + 1, 1, 1)
    query['end_time'] = {"$gte": from_date, "$lt": to_date}

    act_docs = col_activity.find(query).distinct("_id")

    total_activities = len(act_docs)

    pipeline = [
        {"$match": {"is_attended": True, "activity_id": {"$in": list(act_docs)}}},
        {"$lookup": {
            "from": "alumni",
            "let": {"person_ref_id": "$person_id"},
            "pipeline": [
                {"$match": {"$expr": {"$eq": ["$_id", "$$person_ref_id"]}}},
                {"$match": {"is_deleted": {"$ne": True}}},
                {"$project": {"name_zh": 1, "_id": 0, "self_label": 1,"has_valid_identify": {
                    "$cond": {
                        "if": {"$and": [
                            {"$ne": ["$identify_photo", None]},
                            {"$ne": ["$identify_id", None]}
                        ]},
                        "then": True,
                        "else": False
                    }
                },}}
            ],
            "as": 'persons'
        }},
        {"$match": {"persons.0": {"$exists": True}}},
        {"$facet": {
            "contacts_by_person": [
                {"$group": {"_id": "$person_id", "integrity": {"$sum": "$refs_participants"}, "contacts": {"$sum": 1}}}
            ],
            "self_label_count": [
                {"$match": {"persons.0.self_label": {"$in": ["两院院士", "科协委员", "科协常委,两院院士"]}}},
                {"$group": {"_id": "$person_id","self_label": {"$sum": 1}}}
            ],
            # 新增的统计部分
            "valid_id_count": [
                # 筛选具有有效身份信息的文档
                {"$match": {"persons.0.has_valid_identify": True}},
                # 聚合统计具有有效身份证件的总数
                {"$count": "total_valid_identify"}
            ]
        }}
    ]

    data = list(col_register.aggregate(pipeline))
    total_participants = 0
    refs_participants = 0

    # 质量指标
    quality_index_count = 0
    # 激活指标
    activate_indicators_count = 0
    # 数量指标
    quantity_indicators_count = 0

    docs = data[0].get("contacts_by_person", [])

    self_labels = data[0].get("self_label_count", [])

    valid_id_count = data[0].get("valid_id_count", [])

    print(valid_id_count)

    # 有效身份证件数量
    if valid_id_count:
        quantity_indicators_count = valid_id_count[0].get("total_valid_identify", 0)


    for self_label in self_labels:
        activate_indicators_count += 1
        if self_label.get("self_label", 0) > 0:
            quality_index_count += self_label.get("self_label", 0)

    for doc in docs:
        _contact = doc.get("contacts")
        _integrity = doc.get("integrity")
        # 计算活动联系服务科技 工作者基础人次数
        if _contact >= 2:
            total_participants += 2
        else:
            total_participants += _contact

        # 活动联系服务科工作者加分人次数
        if _integrity >= 2:
            refs_participants += 2
        else:
            refs_participants += _integrity

        # 两院院士加分  0-20人	60%	3*60%=1.8分
        # 21-50人	70%	3*70%=2.1分
        # 50-100人	80%	3*80%=2.4分
        # 101-200人	90%	3*90%=2.7分
        # 201以上	100%	3*100%=3分


    total_service = total_participants + refs_participants
    okr = col_okr.find_one({"year": year, "dept_id": inst_id})
    if okr:
        ration = round(total_service / okr.get("okr", 0.000001), 6)
        col_top11e.update_one({"dept_id": inst_id, "year": year},
                              {"$set": {"total_activities": total_activities,
                                        "total_participants": total_participants,
                                        "quality_index_count" : quality_index_count,
                                        "activate_indicators_count" : activate_indicators_count,
                                        "quantity_indicators_count":quantity_indicators_count,
                                        "refs_participants": refs_participants,
                                        "total_service": total_service,
                                        "target": okr.get("okr", 0.000001),
                                        "ration": ration,
                                        "num_of_alumni": len(docs),
                                        "label": okr.get("dept_label"),
                                        "update": datetime.utcnow()
                                        }}, upsert=True)


if __name__ == '__main__':
    # 62b945cd9aebef53937fecca
    okr = col_okr.find()
    for o in okr:
        dept = o.get("dept_id")
        for m in [(2023, 1), (2023, 2), (2023, 3), (2023, 4), (2023, 5), (2023, 6), (2023, 7), (2023, 8), (2023, 9),
                  (2023, 10), (2023, 11), (2023, 12)]:
            year, month = m
            task_top_by_month(inst_id=dept, year=year, month=month)
            break

    okr = col_okr.find()
    for o in okr:
        dept = o.get("dept_id")
        task_top_ranking_v2(dept)
